/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "zobjects_stdio.h"

#include <sys/types.h>
#include <sys/types.h>
#if defined(__linux__)
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <pthread.h>
#elif defined(_WIN32)
#include <windows.h>
#include <stdio.h> 
#endif

#if defined(__linux__)
#define PID	pid_t
#define TID	pthread_t
#elif defined(_WIN32)
#define PID	HANDLE
#define TID	HANDLE
#endif

struct ZlangDirectProperty_execmd
{
	FILE		*fp ;
	PID		pid ;
	TID		tid ;
	unsigned char	is_halfclose ;
} ;

#if defined(__linux__)
static int dpopen( char *cmd , FILE **fp , PID *pid , TID *tid )
{
	int		fd[2] ;
	int		nret = 0 ;
	
	nret = socketpair( AF_UNIX , SOCK_STREAM , 0 , fd ) ;
	if( nret == -1 )
		return -1;
	
	(*pid) = fork() ;
	if( (*pid) == -1 )
	{
		close( fd[0] );
		close( fd[1] );
		return -2;
	}
	else if( (*pid) == 0 )
	{
		close( fd[0] );
		
		if( fd[1] != STDIN_FILENO )
		{
			nret = dup2( fd[1] , STDIN_FILENO ) ;
			if( nret == -1 )
			{
				close( fd[1] );
				return -301;
			}
		}
		
		if( fd[1] != STDOUT_FILENO )
		{
			nret = dup2( fd[1] , STDOUT_FILENO ) ;
			if( nret == -1 )
			{
				close( fd[1] );
				return -302;
			}
		}
		
		close( fd[1] );
		
		execl( "/bin/sh" , "sh" , "-c" , cmd , NULL );
		_exit( 127 );
	}
	else
	{
		close( fd[1] );
		
		(*fp) = fdopen( fd[0] , "r+" ) ;
		if( (*fp) == NULL )
		{
			close( fd[0] );
			return -311;
		}
		
		return 0;
	}
}

static int dphalfclose( FILE *fp )
{
	int		nret = 0 ;
	
	fflush( fp );
	
	nret = shutdown( fileno(fp) , SHUT_WR ) ;
	if( nret == -1 )
		return -1;
	
	return 0;
}

static int dpclose( FILE *fp , PID pid , TID tid )
{
	PID		waitpid_return ;
	int		status ;
	
	fclose( fp );
	
	do
	{
		waitpid_return = waitpid( pid , & status , 0 ) ;
	}
	while( waitpid_return == -1 && errno == EINTR );
	if( waitpid_return == -1 )
		return -1;
	
	return 0;
}
#elif defined(_WIN32)
#define BUFSIZE 1024

static int dpopen( char *cmd , FILE **fp , PID *pid , TID *tid )
{
	char			pipe_name[ PATH_MAX ] ;
	SECURITY_ATTRIBUTES	attr ;
	HANDLE			fh ;
	STARTUPINFO		si ;
	PROCESS_INFORMATION	pi ;
	int			fd ;
	FILE			*_fp = NULL ;
	BOOL			bret ;
	int			nret = 0 ;

	memset( pipe_name , 0x00 , sizeof(pipe_name) );
	snprintf( pipe_name , sizeof(pipe_name)-1 , "\\\\.\\pipe\\zlang_stdio_execmd_dpipe_0x%p" , cmd );
	memset( & attr , 0x00 , sizeof(SECURITY_ATTRIBUTES) );
	attr.nLength = sizeof(SECURITY_ATTRIBUTES) ;
	attr.bInheritHandle = TRUE ;
	attr.lpSecurityDescriptor = NULL ;
	fh = CreateNamedPipe( pipe_name , PIPE_ACCESS_DUPLEX , PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT , PIPE_UNLIMITED_INSTANCES , BUFSIZE , BUFSIZE , 0 , NULL ) ;
	if( fh == INVALID_HANDLE_VALUE )
		return -1;

	bret = ConnectNamedPipe( fh , NULL ) ;
	if( bret != TRUE )
		return -1;

	fd = _open_osfhandle( (intptr_t)fh , _O_RDWR ) ;
	if( fd == -1 )
		return -321;

	_fp = _fdopen( fd , "r+" ) ;
	if( _fp == NULL )
		return -311;

	memset( & si , 0x00 , sizeof(STARTUPINFO) );
	si.cb = sizeof(STARTUPINFO); 
	si.hStdError = fh;
	si.hStdOutput = fh;
	si.hStdInput = INVALID_HANDLE_VALUE ;
	si.dwFlags |= STARTF_USESTDHANDLES ;
	memset( & pi , 0x00 , sizeof(PROCESS_INFORMATION) );
	bret = CreateProcess( NULL , cmd , NULL , NULL , TRUE , 0 , NULL , NULL , & si , & pi ) ;
	if( bret != TRUE )
		return -2;

	if( fp )
		(*fp) = _fp ;
	if( pid )
		(*pid) = pi.hProcess ;
	if( tid )
		(*tid) = pi.hThread ;
	return 0;
}

static int dphalfclose( FILE *fp )
{
	return 0;
}

static int dpclose( FILE *fp , PID pid , TID tid )
{
	DWORD		dw ;
	HANDLE		fh ;

	dw = WaitForSingleObject( pid , INFINITE );
	if( dw != WAIT_OBJECT_0 )
		return -1;
	
	CloseHandle( pid );
	CloseHandle( tid );
	
	fh = (HANDLE)_get_osfhandle( _fileno(fp) ) ;
	if( fh == NULL )
		return -2;

	fclose(fp);

	return 0;
}
#endif

#if defined(__linux__)

ZlangInvokeFunction ZlangInvokeFunction_execmd_Execute_string;
int ZlangInvokeFunction_execmd_Execute_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*cmd = NULL ;
	int32_t					dpopen_return ;
	
	if( direct_prop->fp != NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & cmd , NULL );
	// GetDataPtr( rt , in1 , (void**) & cmd , NULL );
	dpopen_return = dpopen( cmd , & (direct_prop->fp) , & (direct_prop->pid) , & (direct_prop->tid) ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "nret[%"PRIi32"] = dpopen( \"%s\" , &\"%p\" , &\"%d\" ) ;" , dpopen_return , cmd , direct_prop->fp , (int)(direct_prop->pid) )
	CallRuntimeFunction_int_SetIntValue( rt , out1 , dpopen_return );
	
	direct_prop->is_halfclose = 0 ;
	
	if( dpopen_return )
		return ThrowErrorException( rt , EXCEPTION_CODE_GENERAL , EXCEPTION_MESSAGE_DPOPEN_FAILED );
	else
		return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_CloseWrite;
int ZlangInvokeFunction_execmd_CloseWrite( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					dphalfclose_return ;
	
	if( direct_prop->fp == NULL || direct_prop->is_halfclose == 1 )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	dphalfclose_return = dphalfclose( direct_prop->fp ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%d] = dphalfclose( \"%p\" ) ;" , dphalfclose_return , direct_prop->fp )
	CallRuntimeFunction_int_SetIntValue( rt , out1 , dphalfclose_return );
	
	direct_prop->is_halfclose = 1;
	
	if( dphalfclose_return )
		return ThrowErrorException( rt , EXCEPTION_CODE_GENERAL , EXCEPTION_MESSAGE_DPHALFCLOSE_FAILED );
	else
		return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Close;
int ZlangInvokeFunction_execmd_Close( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					dpclose_return ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	dpclose_return = dpclose( direct_prop->fp , direct_prop->pid , direct_prop->tid ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%d] = dpclose( \"%p\" , \"%d\" ) ;" , dpclose_return , direct_prop->fp , (int)(direct_prop->pid) )
	CallRuntimeFunction_int_SetIntValue( rt , out1 , dpclose_return );
	
	direct_prop->fp = NULL ;
	
	if( dpclose_return )
		return ThrowErrorException( rt , EXCEPTION_CODE_GENERAL , EXCEPTION_MESSAGE_DPCLOSE_FAILED );
	else
		return 0;
}

static TLS char	_g_zlang_string_buffer[ 4096 ] = "" ;

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_string;
int ZlangInvokeFunction_execmd_Scan_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_STRING_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_short;
int ZlangInvokeFunction_execmd_Scan_short( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_SHORT_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_ushort;
int ZlangInvokeFunction_execmd_Scan_ushort( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_USHORT_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_int;
int ZlangInvokeFunction_execmd_Scan_int( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_INT_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_uint;
int ZlangInvokeFunction_execmd_Scan_uint( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_UINT_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_long;
int ZlangInvokeFunction_execmd_Scan_long( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_LONG_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_ulong;
int ZlangInvokeFunction_execmd_Scan_ulong( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_ULONG_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_float;
int ZlangInvokeFunction_execmd_Scan_float( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_FLOAT_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scan_double;
int ZlangInvokeFunction_execmd_Scan_double( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FSCANF_DOUBLE_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Scanln_string;
int ZlangInvokeFunction_execmd_Scanln_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	FGETS_STRING_AND_SET_LENGTH_OUTPUT( direct_prop->fp )
	return 0;
}

static int Print( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *str_obj , struct ZlangObject *str_len_obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	char					*data = NULL ;
	int32_t					data_len ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , ZLANG_FATAL_INVOKE_METHOD_RETURN , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	GetDataPtr( rt , str_obj , (void**) & data , & data_len );
	fprintf( direct_prop->fp , "%.*s" , data_len,data );
	
	FromDataPtr( rt , str_len_obj , & data_len , sizeof(int32_t) );
	
	return 0;
}

static int Println( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *str_obj , struct ZlangObject *str_len_obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	nret = Print( rt , obj , str_obj , str_len_obj ) ;
	if( nret )
		return nret;
	
	fprintf( direct_prop->fp , NEWLINE );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Print_string;
int ZlangInvokeFunction_execmd_Print_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = Print( rt , obj , in1 , out1 ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Println_string;
int ZlangInvokeFunction_execmd_Println_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = Println( rt , obj , in1 , out1 ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Print_basetype;
int ZlangInvokeFunction_execmd_Print_basetype( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*tostr = NULL ;
	int			nret = 0 ;
	
	nret = ToString( rt , in1 , & tostr ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	nret = Print( rt , obj , tostr , out1 ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_Println_basetype;
int ZlangInvokeFunction_execmd_Println_basetype( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*tostr = NULL ;
	int			nret = 0 ;
	
	nret = ToString( rt , in1 , & tostr ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	nret = Println( rt , obj , tostr , out1 ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_FormatPrint_vargs;
int ZlangInvokeFunction_execmd_FormatPrint_vargs( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*buf_obj = NULL ;
	char					*str = NULL ;
	int32_t					str_len ;
	
	int					nret = 0 ;
	
	if( direct_prop->fp == NULL )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	buf_obj = CloneStringObjectInTmpStack( rt , NULL ) ;
	if( buf_obj == NULL )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	nret = CallRuntimeFunction_string_AppendFormatFromArgsStack( rt , buf_obj ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	GetDataPtr( rt , buf_obj , (void**) & str , & str_len );
	
	fprintf( direct_prop->fp , "%.*s" , str_len,str );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_execmd_FormatPrintln_vargs;
int ZlangInvokeFunction_execmd_FormatPrintln_vargs( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	nret = ZlangInvokeFunction_execmd_FormatPrint_vargs( rt , obj ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	fprintf( direct_prop->fp , NEWLINE );
	
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_execmd;
void *ZlangCreateDirectProperty_execmd( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*execmd_prop = NULL ;
	
	execmd_prop = (struct ZlangDirectProperty_execmd *)ZLMALLOC( sizeof(struct ZlangDirectProperty_execmd) ) ;
	if( execmd_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( execmd_prop , 0x00 , sizeof(struct ZlangDirectProperty_execmd) );
	
	return execmd_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_execmd;
void ZlangDestroyDirectProperty_execmd( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_execmd	*execmd_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( execmd_direct_prop->fp )
	{
		int32_t		dpclose_return ;
		
		dpclose_return = dpclose( execmd_direct_prop->fp , execmd_direct_prop->pid , execmd_direct_prop->tid ) ;
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "[%d] = dpclose( \"%p\" , \"%d\" ) ;" , dpclose_return , execmd_direct_prop->fp , (int)(execmd_direct_prop->pid) )
		execmd_direct_prop->fp = NULL ;
	}
	
	ZLFREE( execmd_direct_prop );
	
	return;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_execmd;
void ZlangSummarizeDirectPropertySize_execmd( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_execmd) )
	return;
}

static struct ZlangDirectFunctions direct_funcs_execmd =
	{
		ZLANG_OBJECT_execmd , /* char *ancestor_name */
		
		ZlangCreateDirectProperty_execmd , /* ZlangCreateDirectPropertyFunction *create_entity_func */
		ZlangDestroyDirectProperty_execmd , /* ZlangDestroyDirectPropertyFunction *destroy_entity_func */
		
		NULL , /* ZlangFromCharPtrFunction *from_char_ptr_func */
		NULL , /* ZlangToStringFunction *to_string_func */
		NULL , /* ZlangFromDataPtrFunction *from_data_ptr_func */
		NULL , /* ZlangGetDataPtrFunction *get_data_ptr_func */
		
		NULL , /* ZlangOperatorFunction *oper_PLUS_func */
		NULL , /* ZlangOperatorFunction *oper_MINUS_func */
		NULL , /* ZlangOperatorFunction *oper_MUL_func */
		NULL , /* ZlangOperatorFunction *oper_DIV_func */
		NULL , /* ZlangOperatorFunction *oper_MOD_func */
		
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_NEGATIVE_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_NOT_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_BIT_REVERSE_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_PLUS_PLUS_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_MINUS_MINUS_func */
		
		NULL , /* ZlangCompareFunction *comp_EGUAL_func */
		NULL , /* ZlangCompareFunction *comp_NOTEGUAL_func */
		NULL , /* ZlangCompareFunction *comp_LT_func */
		NULL , /* ZlangCompareFunction *comp_LE_func */
		NULL , /* ZlangCompareFunction *comp_GT_func */
		NULL , /* ZlangCompareFunction *comp_GE_func */
		
		NULL , /* ZlangLogicFunction *logic_AND_func */
		NULL , /* ZlangLogicFunction *logic_OR_func */
		
		NULL , /* ZlangLogicFunction *bit_AND_func */
		NULL , /* ZlangLogicFunction *bit_XOR_func */
		NULL , /* ZlangLogicFunction *bit_OR_func */
		NULL , /* ZlangLogicFunction *bit_MOVELEFT_func */
		NULL , /* ZlangLogicFunction *bit_MOVERIGHT_func */
		
		ZlangSummarizeDirectPropertySize_execmd , /* ZlangSummarizeDirectPropertySizeFunction *summarize_direct_prop_size_func */
	} ;

ZlangImportObjectFunction ZlangImportObject_execmd;
struct ZlangObject *ZlangImportObject_execmd( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_execmd , & direct_funcs_execmd , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		return NULL;
	}
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Execute_string , ZLANG_OBJECT_int , "Execute" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_CloseWrite , ZLANG_OBJECT_int , "CloseWrite" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Close , ZLANG_OBJECT_int , "Close" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_string , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_short , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_short,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_short , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_ushort,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_int , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_int , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_uint,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_long , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_long,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_long , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_ulong,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_float , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_float,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scan_double , ZLANG_OBJECT_int , "Scan" , ZLANG_OBJECT_double,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Scanln_string , ZLANG_OBJECT_int , "Scanln" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_string , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_string , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_bool,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_bool,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_short,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_short,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_ushort,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_ushort,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_uint,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_uint,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_long,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_long,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_ulong,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_ulong,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_float,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_float,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Print_basetype , ZLANG_OBJECT_int , "Print" , ZLANG_OBJECT_double,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_Println_basetype , ZLANG_OBJECT_int , "Println" , ZLANG_OBJECT_double,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_FormatPrint_vargs , ZLANG_OBJECT_int , "FormatPrint" , ZLANG_OBJECT_vargs,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_execmd_FormatPrintln_vargs , ZLANG_OBJECT_int , "FormatPrintln" , ZLANG_OBJECT_vargs,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	return obj ;
}

#endif
